package com.lemon.rpcframe.dao.basedao;

import java.sql.Connection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.lemon.rpcframe.dao.statementcreater.BJ58ProcCSCreater;
import com.lemon.rpcframe.dao.statementcreater.IStatementCreater;
import com.lemon.rpcframe.dao.statementcreater.MysqlPSCreater;

/**
 * 辅助类 
 * 主要用来生成数据库的实例    提供事务等功能
 *
 *
 * @author wangyazhou
 * @version 1.0
 * @date  2015年11月2日 下午1:59:15
 * @see 
 * @since
 */
public class DAOHelper {

    /**
     * log
     */
    private static final Log logger = LogFactory.getLog(DAOHelper.class);

    /**
     * exec sql handle
     */
    public IDAO sql = null;

    /**
     * exec proc handle
     */
    public IDAO proc = null;

    public static DAOHelper createIntrance(String configPath) throws Exception {
        return createDAO(configPath);
    }

    private static DAOHelper createDAO(String configPath) throws Exception {
        ConnectionHelper ch = new ConnectionHelper(configPath);

        DAOHelper dao = new DAOHelper(ch);

        AbstractDAO sqlDAO = null;

        String sqlCreaterClass = "com.bj58.zptask.dtplat.jobnode.dao.statementcreater.MysqlPSCreater";
        logger.info("init SqlCreaterClass:" + sqlCreaterClass);
        //        IStatementCreater creater = (IStatementCreater) Class.forName(sqlCreaterClass).newInstance();
        IStatementCreater creater = new MysqlPSCreater();
        sqlDAO = new DAOHandler(creater);
        sqlDAO.connHelper = ch;

        AbstractDAO procDAO = null;
        String procCreaterClass = "com.bj58.zptask.dtplat.jobnode.dao.statementcreater.BJ58ProcCSCreater";

        logger.info("init ProcCreaterClass:" + procCreaterClass);
        //        IStatementCreater pscreater = (IStatementCreater) Class.forName(procCreaterClass).newInstance();
        IStatementCreater pscreater = new BJ58ProcCSCreater();
        procDAO = new DAOHandler(pscreater);
        procDAO.connHelper = ch;

        dao.sql = sqlDAO;
        dao.proc = procDAO;

        logger.info("create DAOHelper success!");
        return dao;
    }

    public DAOHelper(ConnectionHelper connHelper) {
        this.connHelper = connHelper;
    }

    private ConnectionHelper connHelper;

    //    @Deprecated
    //    public ConnectionPool getConnPool() {
    //        return connHelper.getConnPool();
    //    }
    //
    //    public ConnectionHelper getConnHelper() {
    //        return this.connHelper;
    //    }

    /**
     * 执行事务任务
     * @param tran
     * @throws Exception
     */
    public void execTransaction(ITransaction tran) throws Exception {
        // 事务开始
        beginTransaction();

        try {
            tran.exec();
            //事务提交
            commitTransaction();
        } catch (Exception ex) {
            //事务回滚
            rollbackTransaction();

            throw ex;
        } finally {
            //事务结束
            endTransaction();
        }
    }

    /**
     * 开启事务(默认级别TRANSACTION_READ_COMMITTED)
     * @throws Exception
     */
    public void beginTransaction() throws Exception {
        beginTransaction(Connection.TRANSACTION_READ_COMMITTED);
    }

    /**
     * 开启事务
     * @param level 事务级别
     * @throws Exception
     */
    public void beginTransaction(int level) throws Exception {
        Connection conn = connHelper.get();
        if (conn != null) {
            try {
                conn.setAutoCommit(false);
                conn.setTransactionIsolation(level);
                connHelper.lockConn(conn);
            } catch (Exception ex) {
                logger.error(ex);
            }
        } else {
            throw new Exception("conn is null when beginTransaction");
        }
    }

    /**
     * 提交事务
     * @throws Exception
     */
    public void commitTransaction() throws Exception {
        Connection conn = connHelper.get();
        if (conn != null) {
            conn.commit();
        } else {
            throw new Exception("conn is null when commitTransaction");
        }
    }

    /**
     * 回滚事务
     * @throws Exception
     */
    public void rollbackTransaction() throws Exception {
        Connection conn = connHelper.get();
        if (conn != null) {
            conn.rollback();
        } else {
            throw new Exception("conn is null when rollbackTransaction");
        }
    }

    /**
     * 结束事务
     * @throws Exception
     */
    public void endTransaction() throws Exception {
        Connection conn = connHelper.get();
        if (conn != null) {
            try {
                //恢复默认
                conn.setAutoCommit(true);
                conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

            } finally {
                connHelper.unLockConn();
                connHelper.release(conn);
            }
        } else {
            throw new Exception("conn is null when endTransaction");
        }
    }

    //    public Object execInsert(String sql, IPreparedStatementHandler handler) throws Exception {
    //        return execWithPara(sql, handler);
    //    }
    //
    //    public Object execWithPara(String sql, IPreparedStatementHandler handler) throws Exception {
    //        Connection conn = null;
    //        PreparedStatement ps = null;
    //        try {
    //            conn = connHelper.get();
    //            ps = conn.prepareStatement(sql);
    //            return handler.exec(ps);
    //        } catch (Exception e) {
    //            logger.error("execQuery error sql:" + sql, e);
    //            throw e;
    //        } finally {
    //            JdbcUitl.closeStatement(ps);
    //            connHelper.release(conn);
    //        }
    //    }
    //
    //    public Object execQuery(String sql, IRowCallbackHandler handler) throws Exception {
    //        Connection conn = null;
    //        ResultSet rs = null;
    //        Statement stmt = null;
    //        try {
    //            // 2011-05-24 使用只读连接
    //            //			conn = connHelper.get();
    //            conn = connHelper.getReadConnection();
    //
    //            stmt = conn.createStatement();
    //            rs = stmt.executeQuery(sql);
    //            return handler.exec(rs);
    //        } catch (Exception e) {
    //            logger.error("execQuery error sql:" + sql, e);
    //            throw e;
    //        } finally {
    //            JdbcUitl.closeResultSet(rs);
    //            JdbcUitl.closeStatement(stmt);
    //            connHelper.release(conn);
    //        }
    //    }
    //
    //    public Object execProc(String sql, ICallableStatementHandler handler) throws Exception {
    //        Connection conn = null;
    //        CallableStatement cs = null;
    //        try {
    //            conn = connHelper.get();
    //            cs = conn.prepareCall(sql);
    //            return handler.exec(cs);
    //        } catch (SQLException e) {
    //            logger.error("execCustomProc error " + sql);
    //            throw e;
    //        } finally {
    //            JdbcUitl.closeStatement(cs);
    //            connHelper.release(conn);
    //        }
    //    }
    //
    //    @Deprecated
    //    public Exception execTransaction(ITransactionHandler handler) throws Exception {
    //        Connection conn = null;
    //        Exception exception = null;
    //        try {
    //            IStatementCreater sqlServerCreater = new SqlServerPSCreater();
    //            IStatementCreater mysqlCreater = new MysqlPSCreater();
    //            conn = connHelper.get();
    //            conn.setAutoCommit(false);
    //            try {
    //                handler.exec(conn, sqlServerCreater, mysqlCreater);
    //            } catch (Exception ex) {
    //                exception = ex;
    //            }
    //        } catch (SQLException e) {
    //            logger.error("execCustomProc error " + sql);
    //            throw e;
    //        } finally {
    //            try {
    //                conn.commit();
    //            } catch (Exception e) {
    //                e.printStackTrace();
    //            }
    //            connHelper.release(conn);
    //        }
    //
    //        return exception;
    //    }

}